/**
 * @author huangsiwei
 */
(function() {
	"use strict";

	$.geneGrid = {
		basePath : jsContextPath ? jsContextPath + '/' : '',
		grids : []
	};

	// 监听window的resize事件，对grid进行缩放
	$(window).resize(function() {
		var grids = $.geneGrid.grids;
		for ( var i in grids) {
			var gridItem = grids[i];
			var grid = $(gridItem.grid), parent = gridItem.parent;
			grid.setGridWidth(parent.width());
		}
	});

	$.fn.geneGrid = function(config, grid) {
		return this
				.each(function() {
					var self = this;

					var gridItem = {
						grid : self,
						parent : $(self).parent()
					};
					$.geneGrid.grids.push(gridItem);

					var defaultConfig = $
							.extend(
									true,
									{
										formId : 'queryForm',// 默认查询条件form的id
										paramObj : {},// 自定义的查询参数
										reportType : null,// 对应后台查询的SQL id
										treeGrid : false,// 是否是tree grid
										multOprtJoin : ';',// 可多选的查询条件的连接符
										pagination : true,// 是否使用分页，treeGrid为false时才起作用
										treeConfig : {
											initNodeid : null,// 树的初始化节点的节点id
											nodeidField : null,// 节点id对应的字段名
											parentFiled : null,// 父节点对应的字段名
											expandLevel : 0
										// 树初始化后展开的层次，0为不展开
										},
										useDynamicCol : false,// 是否动态加载列
										dynamicCol : {// useDynamicCol为true生效
											configBeanName : null,// 动态加载列时的配置bean的名称
											beforeDynamicCol : null, // 动态加载列后的回调函数
											afterDynamicCol : null, // 动态加载列后的回调函数,即在表格结果加载完成后
											hiddenCol : false,// 隐藏维度
											hiddenMeasure : false, // 隐藏度量
											noData : {
												title : '提示',
												context : '无相关结果',
												template : '<p style="font-size:14px;height:22px;line-height:22px;color:#323232;font-weight:bold;text-align:center;white-space:nowrap;">{0}</p><p style="font-size:12px;height:18px;line-height:18px;color:#323232;text-align:center;white-space:nowrap;">{1}</p>',
												format : function(template,
														title, context) {
													return $.jgrid.format(
															template, title,
															context);
												}
											}
										},
										cellSpan : {// 是否启用合并单元
											enable : false
										},
										topTotal : {// 上合计，将合计加于所有记录之前。如有分页仅第一页有。
											enable : false,// 是否使用上合计
											rowClass : 'total',// 行class name
											defaultLabel : '合计',// 合计显示名
											/**
											 * cellProps示例 [{ name :'字段名1', //
											 * request label : '总计1', //
											 * 为空则使用defaultLabel colspan : 2
											 * ,//TD的colspan classp :
											 * 'total2',//TD的class cssp :
											 * {color:'#FFFFFF'}, //TD的css attrp :
											 * {title:'这是一个自定义样式的合计行'}
											 * //TD的attribute }]
											 */
											cellProps : null,// 列定义
											beforeAppend : null
										},
										bottomTotal : {// 低合计，将合计加于所有记录之后。如有分页仅最后一页有。
											enable : false,// 是否使用上合计
											rowClass : 'total',// 行class name
											defaultLabel : '合计',// 合计显示名
											cellProps : null,// 列定义，参考topTotal的cellProps
											beforeAppend : null
										},
										custom : {
											nodata : {
												enable : true,
												target : self,
												icon : 'table',
												refresh : function() {
													var tsDiv = $('#gbox_' + this.id);
													$.utils.noData
															.hideNoDataInfo(tsDiv);
													$('#' + this.id).doFind();
												},
												css : null
											}
										}
									}, config || {});

					var defaultGeneOption = {
						mtype : "POST",
						datatype : "json",
						height : "auto",
						gridview : false,
						jsonReader : {
							repeatitems : false,
							cell : '',
							id : '0'
						},
						autowidth : true,
						altRows : true,
						pager : null,
						altclass : 'greybg'// 默认的隔行换色
					};
					var defaultGridView = {
						url : $.geneGrid.basePath + '/grid/grid.do',
						rownumbers : true,
						pager : "#gridPager",
						viewrecords : true,
						rowNum : 20,
						rowList : [ 20, 50, 100 ]
					};
					var defaultGridViewNopage = {
						url : $.geneGrid.basePath + '/grid/grid.do',
						rownumbers : true,
						pager : null,
						rowNum : 10000
					};
					var defaultTreeView = {
						url : $.geneGrid.basePath + '/grid/treeGrid.do',
						treeGrid : true,
						treeGridModel : 'adjacency',
						ExpandColumn : null,
						ExpandColClick : true,
						treeIcons : {
							plus : 'ui-icon-circle-plus',
							minus : 'ui-icon-circle-minus',
							leaf : 'ui-icon-document-b'
						}
					};
					var defaultView = defaultConfig.treeGrid ? defaultTreeView
							: (defaultConfig.pagination ? defaultGridView
									: defaultGridViewNopage);
					if (defaultConfig.treeGrid) {
						$(self).addClass('treeGrid');
						defaultView.ExpandColumn = defaultConfig.ExpandColumn;
					}

					defaultGeneOption = $.extend(true, defaultGeneOption,
							defaultView, grid || {});

					// defaultGeneOption.postData = getPostData(defaultConfig);
					var beforeRequest = defaultGeneOption.beforeRequest;
					defaultGeneOption.beforeRequest = function() {// 解决自定义函数覆盖问题

						var cellSpan = defaultConfig.cellSpan;
						if (cellSpan && !cellSpan.init) {
							cellSpan.init = true;
							var cells = getSpanCells(this);
							this.config.spanCells = cells.join(',');
						}

						$(this).setGridParam( {
							postData : getPostData(this.config)
						});

						var tsDiv = $('#gbox_' + this.id);
						// 显示loading
						tsDiv.hide();
						$.utils.loading.show(tsDiv.parent());

						if ($.isFunction(beforeRequest)) {
							beforeRequest.call(this);
						}
					};

					var loadComplete = defaultGeneOption.loadComplete;
					defaultGeneOption.loadComplete = function(data) {// 解决自定义函数覆盖问题
						var ts = this;// table
						if (data && data.rows) {
							var rows = data.rows;
							if (defaultConfig.treeGrid) {
								window
										.setTimeout(function() {// jqGrid的expandNode会判断this.grid.hDiv.loading，加个0延时
													var level = defaultConfig.treeConfig.expandLevel || 0;
													expandLevel(ts, rows, level);// 第一个参数如果使用self,在调用GridUnload后仍是上一个table的引用
												}, 0);
							}

						}

						var tsDiv = $('#gbox_' + ts.id);
						// 隐藏loading
						$.utils.loading.hide(tsDiv.parent());
						tsDiv.show();

						// 设置无相关结果
						if (rows.length > 0) {
							$.utils.noData.hideNoDataInfo(tsDiv);
							tsDiv.parent().css( {
								'height' : 'auto'
							});
						} else {
							$.utils.noData.showNoDataInfo(tsDiv,
									defaultConfig.custom.nodata);
							if (defaultConfig.custom.nodata.enable) {
								tsDiv.parent().css( {
									'height' : '250'
								});
							}
						}

						if ($.isFunction(loadComplete)) {
							loadComplete.call(ts, data);// 第一个参数如果使用self,在调用GridUnload后仍是上一个table的引用
						}
						addTotalRow(data, ts);
					};

					requestGrid(self, defaultConfig, defaultGeneOption);
				});

	};

	/**
	 * 不使用$.fn而使用$.jgrid将属性extend到jqgrid中
	 * 可使用$.fn.jqGrid(methodName)访问可防止与其他插件命名冲突
	 */
	$.jgrid
			.extend( {
				doFind : function() {
					var selector = this.selector;
					this.each(function() {
						var ts = this;
						var config = ts.config;
						var gridOption = ts.gridOption;
						if (!config || !gridOption) {
							return;
						}
						if (config.useDynamicCol || config.cellSpan.enable) {
							$(ts).GridUnload();

							// jqGrid.GridUnload是重新createElement，所以要重新获取jQuery对象
							// $(selector).geneGrid(config, gridOption);
							requestGrid($(selector)[0], config, gridOption);
						} else {
							$(ts).setGridParam( {
								datatype : 'json',
								page : 1,
								postData : getPostData(config)
							});
							$(ts).trigger("reloadGrid");
						}
					});
				},
				getGridConfig : function(pName) {
					var $t = this[0];
					if (!$t || !$t.grid) {
						return;
					}
					if (!pName) {
						return $t.config;
					} else {
						return typeof ($t.config[pName]) != "undefined" ? $t.config[pName]
								: null;
					}
				},
				setGridConfig : function(newParams) {
					return this.each(function() {
						if (this.grid && typeof (newParams) === 'object') {
							$.extend(true, this.config, newParams);
						}
					});
				},
				getGridGridOption : function(pName) {
					var $t = this[0];
					if (!$t || !$t.grid) {
						return;
					}
					if (!pName) {
						return $t.gridOption;
					} else {
						return typeof ($t.gridOption[pName]) != "undefined" ? $t.gridOption[pName]
								: null;
					}
				},
				setGridGridOption : function(newParams) {
					return this.each(function() {
						if (this.grid && typeof (newParams) === 'object') {
							$.extend(true, this.gridOption, newParams);
						}
					});
				}
			});
	var oldFmatter = $.fn.fmatter;// $.fn.fmatter有好多属性，此处只覆盖其function，故先将其缓存起来
	$.fn.fmatter = function(formatType, cellval, opts, rwd, act) {
		// build main options before element iteration
		var v = cellval;
		opts = $.extend( {}, $.jgrid.formatter, opts);

		try {
			v = $.fn.fmatter[formatType].call(this, cellval, opts, rwd, act);
		} catch (fe) {
		}
		try {
			// ******新增功能*****//
			// 如果定义了cellClick则加上A标签和点击事件
			var cm = opts.colModel;
			var cellClick = cm.cellClick;
			if (cellClick) {
				v = "<a id=\""
						+ opts.gid
						+ "_"
						+ opts.rowId
						+ "_"
						+ opts.pos
						+ "\" href=\"javascript:;\" onclick=\"javascript:jQuery.fn.fmatter.linkactionCall('"
						+ cellval + "','" + opts.rowId + "','" + opts.gid
						+ "'," + opts.pos + ");\">" + v + "</a>";
			}
		} catch (e) {
		}
		return v;
	};
	$.extend($.fn.fmatter, oldFmatter);

	$.fn.fmatter.linkactionCall = function(cellval, rid, gid, pos) {
		rid = $.jgrid.jqID(rid);
		gid = $.jgrid.jqID(gid);
		var table = $('#' + gid);
		var cm = $('#' + gid)[0].p.colModel[pos];
		var action = cm.cellClick;
		if ($.isFunction(action)) {
			action.call(table, cellval, rid, gid, cm, pos);
		}
	};

	/**
	 * 展开树到指定层级 modify by HuangWenJing
	 */
	function expandLevel(ts, rows, level) {
		if (!ts.expandQueue) {
			ts.expandQueue = [];
		}
		for ( var r = 0; r < rows.length; r++) {
			ts.expandQueue[ts.expandQueue.length] = rows[r];
		}

		if (ts.expandQueue.length == 0) {
			return;
		}

		var idn = ts.p.jsonReader.id;
		if (isNaN(idn)) {
			idn = 0;
		}

		var idField = ts.p.colModel[idn].name;
		var _index = $(ts).jqGrid('getGridParam', '_index');// 行Id与行号的键值对
		var $data = $(ts).jqGrid('getGridParam', 'data');// 表数据数组

		var row = ts.expandQueue.pop();
		var pos = _index[row[idField]];
		var rowData = $data[pos];

		var nodeDepth = rowData.level// 行的层级

		if (nodeDepth < level) {
			$(ts).jqGrid('expandNode', rowData);
		} else {
			expandLevel(ts, [], level);
		}
	}
	;

	/**
	 * 初始化grid
	 */
	function requestGrid(ts, config, gridOption) {
		ts.config = config;// 缓存参数
		ts.gridOption = gridOption;
		if (config.useDynamicCol) {
			initDynamicCol(ts, config, gridOption);
		} else {
			$(ts).jqGrid(gridOption);
		}
	}

	/**
	 * 获取form表的参数
	 */
	function getFormData(formId, multOprtJoin) {
		var param = {};
		if (multOprtJoin) {
			param.multOprtJoin = multOprtJoin;
		}
		var inputs = $('#' + formId + ' :input');
		inputs.each(function() {
			var name = $(this).attr('name');
			var val = $(this).val();

			if (name && name.length > 0 && val !== null
					&& typeof (val) !== 'undefined') {
				if (typeof val !== 'string') {// 多选下拉框等
					val = val.join(multOprtJoin);
				}
				param[name] = val;
			}
		});
		return param;
	}

	/**
	 * 获取所有要请求的参数
	 */
	function getPostData(config) {
		var formId = config.formId;
		var multOprtJoin = config.multOprtJoin;
		var postData = formId ? getFormData(formId, multOprtJoin) : {};
		$.extend(postData, config.paramObj);

		postData.reportType = config.reportType;
		postData.useDynamicCol = config.useDynamicCol;
		postData.spanCells = config.spanCells;
		if (postData && config.dynamicCol) {
			postData.configBeanName = config.dynamicCol.configBeanName;
		}

		if (!config.treeGrid && !config.pagination) {
			postData.pagination = false;
		}
		if (config.treeGrid) {
			if (config.treeConfig) {
				$.extend(postData, config.treeConfig);
			}
			if (config.ExpandColumn) {
				postData.ExpandColumn = config.ExpandColumn;
			}
		}

		if (config.topTotal && config.topTotal.enable) {
			postData.topTotal = true;
		}
		if (config.bottomTotal && config.bottomTotal.enable) {
			postData.bottomTotal = true;
		}
		return postData;
	}

	function initDynamicCol(ts, config, gridOption) {
		if (ts.loading) {// 防重判断，防止重复update导致表头嵌套
			return;
		}
		ts.loading = true;
		$.ajax( {
			url : $.geneGrid.basePath + '/grid/dynamicCol.do',
			type : 'post',
			data : getPostData(config),
			dataType : 'json',
			success : function(data) {
				var hiddenCol = config.dynamicCol.hiddenCol;// 隐藏维度
			var hiddenMeasure = config.dynamicCol.hiddenMeasure;// 隐藏度量

			// 无数据
			if (!data || !data.headerList || !data.columnList
					|| data.headerList.length === 0
					|| data.columnList.length === 0) {
				var noData = config.dynamicCol.noData || {};
				var title = noData.title || '';
				var context = noData.context || '';
				var template = noData.template || '';
				var format = noData.format;
				if ($.isFunction(format)) {
					var nd = format.call(ts, template, title, context);
					if (nd) {
						var width = gridOption.width || '100%';
						$(ts).width(width);
						$(ts).append('<tr><td>' + nd + '</td></tr>');
					}
				}
				ts.loading = false;
				return;
			}// end 无数据

			var headers = data.headerList;
			var columns = data.columnList;
			var isSimpleCol = true;
			if (hiddenCol && !hiddenMeasure) {
				headers = null;
			} else if (!hiddenCol && hiddenMeasure) {
				for ( var i = 0; i < headers.length; i++) {// 判断度量值是否只有一个
					if (headers[i].numberOfColumns > 1) {
						isSimpleCol = false;
					}
				}
				if (isSimpleCol) {// 只有numberOfColumns都为一时才可以将headers转成columns
					// 对只有一个度量值的grid，如果隐藏度量值，则将headers的label放入columns中，以使得grid仍sortable
					changeCols(columns, headers);
					headers = null;
				}
			} // hiddenCol && hiddenMeasure 暂不支持 。
			// !hiddenCol && !hiddenMeasure无须处理

			var treeGrid = config.treeGrid;
			var colModel = [], colNames = [];
			for ( var colIndex = 0; colIndex < columns.length; colIndex++) {
				var col = columns[colIndex];
				col = $.extend(col || {},
						{
							name : col.alias,
							hidden : treeGrid ? colIndex < 2 || col.hidden
									: col.hidden, // 默认前两列是id和parentId,故隐藏
							sortable : !treeGrid,
							formatter : null
						// 不为undefined即可使用cellClick
						});
				colModel.push(col);
			}

			// 回调
			if (config && config.dynamicCol
					&& config.dynamicCol.beforeDynamicCol) {
				var beforeDynamicCol = config.dynamicCol.beforeDynamicCol;
				if ($.isFunction(beforeDynamicCol)) {
					beforeDynamicCol.call(ts, colModel, headers);
				}
			}

			gridOption.colModel = colModel;
			gridOption.headers = headers;
			self.gridOption = gridOption;

			$(ts).jqGrid(gridOption);

			if (headers !== null) {
				$(ts).jqGrid('setGroupHeaders', {
					useColSpanStyle : true,
					groupHeaders : headers
				});

				if (!hiddenCol && hiddenMeasure && !isSimpleCol) {// grid
					// 不止一个度量值，hidden列维度
					var $gview = $(ts).parents(".ui-jqgrid-view");
					var $htable = $("table.ui-jqgrid-htable", $gview);
					$htable.find('tr.jqg-third-row-header').hide();// 隐藏度量值行

					// 下面是调整列维度行的高度，参照jqGrid的setGroupHeaders函数源码
					// 清除高度
					$htable.find('span.ui-jqgrid-resize').css( {
						height : ''
					});
					// 清除top
					$htable.find("div.ui-jqgrid-sortable").css( {
						'top' : ''
					});
					// 换class
					$htable.find("th.ui-th-column-header").each(function() {
						$(this).removeClass('ui-th-column-header');
						$(this).addClass('ui-th-column');
					});
				}
			}

			// 回调
			if (config && config.dynamicCol
					&& config.dynamicCol.afterDynamicCol) {
				var afterDynamicCol = config.dynamicCol.afterDynamicCol;
				if ($.isFunction(afterDynamicCol)) {
					afterDynamicCol.call(ts);
				}
			}
			ts.loading = false;
		}
		});
	}

	function changeCols(columns, headers) {
		for ( var i = 0; i < columns.length; i++) {
			var col = columns[i];
			for ( var j = 0; j < headers.length; j++) {
				var header = headers[j];
				if (col.alias === header.startColumnName) {
					col.label = header.titleText;
					break;
				}
			}
		}
	}

	/**
	 * 插入合计行
	 * 
	 * @author huangsiwei
	 */
	function addTotalRow(data, table) {
		if (table.p.reccount === 0) {// 无数据
			return;
		}
		var totalData, topRow, bottomRow, base, from, to, tot, oldPagingInfo;
		base = parseInt(table.p.page, 10) - 1;
		if (base < 0) {
			base = 0;
		}
		base = base * parseInt(table.p.rowNum, 10);
		to = base + table.p.reccount;
		tot = table.p.records;
		from = base + 1;

		var pgboxes = table.p.pager ? table.p.pager : "";
		pgboxes += table.p.toppager ? (pgboxes ? "," + table.p.toppager
				: table.p.toppager) : "";
		if (pgboxes) {// 将pager缓存
			oldPagingInfo = $(".ui-paging-info", pgboxes).html();
		}
		if (data && data.userdata && (totalData = data.userdata.totalRow)) {
			var colModel = table.p.colModel;
			var config = table.config;
			var topTotal = config.topTotal;
			var bottomTotal = config.bottomTotal;
			var topAppend, bottomAppend;

			if (topTotal && topTotal.enable
					&& (from === 1 || table.config.treeGrid === true)) {
				var rowid = $.jgrid.jqID(table.p.id) + '_topTotal';
				topRow = doGetTotalRow(table, topTotal, totalData, rowid);
				appendTotalRow(table, topRow, 'first');
				topAppend = true;
			}

			if (bottomTotal && bottomTotal.enable
					&& (to === tot || !config.pagination/* 当前页是最后一页或者不分页 */
					|| table.config.treeGrid === true)) {
				var rowid = $.jgrid.jqID(table.p.id) + '_bottomTotal';
				bottomRow = doGetTotalRow(table, bottomTotal, totalData, rowid);
				appendTotalRow(table, bottomRow, 'last');
				bottomAppend = true;
			}

			var rownums = $('.jqgrid-rownum', table);
			var rowTot = rownums.size();

			// 如果有序号列，更新序号
			rownums.each(function(i) {
				if ((i === 0 && topAppend)
						|| (i === rowTot - 1 && bottomAppend)) {
					$(this).html('&nbsp;');
				} else if (i > 0 && topAppend) {
					var rownum = $(this).html();
					$(this).html(parseInt(rownum, 10) - 1);
				}
			});

			if (pgboxes) {// 重新写入分页信息
				$(".ui-paging-info", pgboxes).html(oldPagingInfo);
			}
		}
	}

	/**
	 * 把合计行的格式定义转换成符合数据的格式
	 * 
	 * @param table
	 *            table的dom
	 * @param totalConfig
	 *            汇总行格式定义
	 * @param rowData
	 *            行数据
	 * @param rowid
	 *            行Id
	 * 
	 * @author huangsiwei
	 */
	function doGetTotalRow(table, totalConfig, rowData, rowid) {
		var colModel, config, gi, si, ni, cellProps, row = {}, cells = [];
		colModel = table.p.colModel;
		config = table.config;
		cellProps = totalConfig.cellProps;
		cellProps = $.isArray(cellProps) ? cellProps : [];
		row.rowData = rowData = $.extend(true, {}, rowData);// clone
		row.cells = cells;
		row.rowid = rowid;
		row.beforeAppend = totalConfig.beforeAppend;// 回调
		row.rowClass = totalConfig.rowClass;// TR样式
		ni = table.p.rownumbers === true ? 1 : 0;// 是否有序号列
		gi = table.p.multiselect === true ? 1 : 0;// 是否有多选列
		si = table.p.subGrid === true ? 1 : 0;// 是否有subGrid列
		var lastCell = null;
		for ( var i = gi + si + ni; i < colModel.length; i++) {
			var cm = colModel[i], hasCp = false;
			if ((cm.columnType !== 'COL_DIM' /* 度量列 */
					&& cm.columnType !== 'TOTAL'/* 列合计 */
			&& cm.totalCol !== true/* 为非动态列新增的属性 */) && !cm.hidden) {

				// 查看该列是否在cellProps中有定义
				var cp = findCp_(cm.name, cellProps);
				if (cp !== null) {// 如果有则用改定义来配置列的样式
					lastCell = null;
					var cell = {// 首列使用cellProp定义覆盖
						name : cp.name,
						pos : i++,
						value : cp.label || totalConfig.defaultLabel,
						classp : cp.classp || '',
						cssp : $.extend(true, {
							'text-align' : 'center'
						}, cp.cssp || {}),
						attrp : $.extend(true, {
							colspan : cp.colspan
						}, cp.attrp || {})
					};
					cells.push(cell);
					for ( var k = 1; k < cp.colspan; k++, i++) {// 将之后的cp.colspan列隐藏
						cm = colModel[i];
						cell = {
							name : cm.name,
							pos : i,
							cssp : {
								display : 'none'
							}
						};
						cells.push(cell);
					}
					i--;
				} else {// 否则合并相邻的列
					var cell;
					if (lastCell == null) {// 如果无上一列或上一列是被cellProps定义的，新建一列colspan为1的列
						lastCell = cell = {
							name : cm.name,
							pos : i,
							value : totalConfig.defaultLabel,
							cssp : {
								'text-align' : 'center'
							},
							attrp : {
								colspan : 1
							}
						};
					} else {
						lastCell.attrp.colspan++;// 将上一列的colspan加1，并将本列隐藏
						cell = {
							name : cm.name,
							pos : i,
							cssp : {
								display : 'none'
							}
						};
					}
					cells.push(cell);
				}
			} else {
				lastCell = null;
			}
		}

		function findCp_(name, cellProps) {
			for ( var i = 0; i < cellProps.length; i++) {
				var cp = cellProps[i];
				if (name === cp.name) {
					return cp;
				}
			}
			return null;
		}

		return row;
	}

	/**
	 * 插入行并改变dom结构
	 * 
	 * @param table
	 *            table的dom
	 * @param row
	 *            object有属性rowid,rowData,cells
	 * @param pos
	 *            first或last
	 * @author huangsiwei
	 */
	function appendTotalRow(table, row, pos) {
		var beforeAppend, appendResult, rowData, rowid, cells;
		beforeAppend = row.beforeAppend;
		rowData = row.rowData;
		rowid = row.rowid;
		cells = row.cells;
		if ($.isFunction(beforeAppend)) {
			appendResult = beforeAppend.call($(table), rowData, cells);
		}
		if (appendResult !== false) {// 如果显式的返回false则不插入此行
			appendResult = $(table).addRowData(rowid, rowData, pos);// 插入
		}
		if (appendResult) {
			var ind = table.rows.namedItem(rowid);
			for ( var i = 0; i < cells.length; i++) {
				var cell = cells[i];
				var tcell = $("td:eq(" + cell.pos + ")", ind);

				var v = cell.value;
				var title = {
					title : v
				};
				if (table.p.treeGrid && $(".tree-wrap", $(tcell)).length > 0) {
					$("span", $(tcell)).html(v).attr(title);
				} else {
					$(tcell).html(v).attr(title);
				}

				if (typeof cell.cssp === 'object') {
					$(tcell).css(cell.cssp);
				}
				if (typeof cell.classp === 'string') {
					$(tcell).addClass(cell.classp);
				}
				if (typeof cell.attrp === 'object') {
					$(tcell).attr(cell.attrp);
				}

			}
			$(ind).addClass(row.rowClass);
		}
		return appendResult;
	}
	;

	function resetGridWidth(ts) {
		var $ts, parent;
		$ts = $(ts), parent = $ts.parent();
		$ts.setGridWidth(parent.width());
	}
	;

	function getSpanCells(ts) {
		var colModel = ts.p.colModel, c = [];
		for ( var i in colModel) {
			var cm = colModel[i];
			if (cm.cellSpan) {
				var cellattr = cm.cellattr;
				cm.cellattr_ = cellattr;
				cm.cellattr = function(rowId, tv, rawObject, cm, rdata) {
					var s = cellSpan(rawObject, cm);
					if ($.isFunction(cm.cellattr_)) {
						s += ' ' + cm
								.cellattr_(rowId, tv, rawObject, cm, rdata);
					}
					return s;
				};
				c.push(cm.name);
			}
		}

		return c;
	}
	;

	function cellSpan(rawObject, cm) {
		var name = cm.name, rowSpan = name + '_RSPAN', rowIdx = name + '_RIDX';

		rowSpan = rawObject[rowSpan];
		rowIdx = rawObject[rowIdx];

		return $.utils.gridCellSpan(rowSpan, rowIdx);
	}
	;
})();